Skip to content

feat(java): raise baseline to 17 and add workflow gates#331

Merged
pratyush618 merged 9 commits into
masterfrom
feat/java-workflows-gates
Jun 29, 2026
Merged

feat(java): raise baseline to 17 and add workflow gates#331
pratyush618 merged 9 commits into
masterfrom
feat/java-workflows-gates

Conversation

@pratyush618

@pratyush618 pratyush618 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Changes

  • Java 17 baselinebuild.gradle.kts compiles with --release 17 (no pinned toolchain; modern JDK compiles, --release blocks newer-API leak). Unlocks records, sealed interfaces, pattern-matching switch, and Spring Boot 3. Pre-1.0 floor bump from 11→17.
  • Workflow approval gates — static-DAG nodes can park WaitingApproval; Queue.approveGate / rejectGate resolve them (approve runs successors, reject skip-cascades). New JNI fns (setWorkflowNodeWaitingApproval, resolveWorkflowGate, …) over the existing taskito-workflows storage; tracker drives gate state. No new core storage.

Tests

Workflow-gate coverage added. ./gradlew build green (Spotless + Checkstyle + tests); native .so bundled.

Notes

Bottom of a stacked series — subsequent PRs (conditions, sub-workflows, sagas, resources, predicates, codecs, FFM fast-path, mesh, …) branch off this one in order.

Summary by CodeRabbit

  • New Features

    • Added workflow approval gates with manual approve/reject and timeout-based auto-resolution.
    • Gate configuration is supported end-to-end, including conditional/deferred node handling and gate lifecycle control via tracker/worker APIs.
    • Added workflow gate builder support and gate-related configuration types.
  • Bug Fixes

    • Improved deferred-node promotion and rejection/skip cascade for correct downstream behavior.
    • Enhanced successor promotion so workflows finalize correctly when fan-in prerequisites complete.
  • Chores

    • Updated Java/Gradle tooling and CI to target Java 17; refreshed JDK coverage and Gradle wrapper to 9.6.1.

Java 11→17 so Spring Boot 3 apps can adopt and to enable records/
sealed types. CI JDK matrix → 17/21/25.
Park a step (WAITING_APPROVAL) until Worker.approveGate/rejectGate or
its timeout resolves it; successors then run. Adds gate/node JNI fns +
workflowNameForRun, GateConfig/GateAction, Step.gate/Workflow.gate, and
a tracker that promotes deferred nodes from registered workflows.
Approve, reject, and timeout (auto-approve/auto-reject) paths.
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 794e7e58-4e46-4df6-936d-c8915f4ee8e0

📥 Commits

Reviewing files that changed from the base of the PR and between 349a521 and 1a6377f.

📒 Files selected for processing (4)
  • crates/taskito-java/src/workflows/mod.rs
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java
🚧 Files skipped from review as they are similar to previous changes (4)
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java
  • crates/taskito-java/src/workflows/mod.rs

📝 Walkthrough

Walkthrough

Adds workflow gate nodes and metadata end-to-end, threads parent run linkage and gate state JNI methods through Java and Rust, implements gate promotion and timeout handling in WorkflowTracker and Worker, adds gate tests, and updates Java build tooling and CI to Java 17.

Changes

Workflow Gate Feature and Java 17 Upgrade

Layer / File(s) Summary
Gate types and workflow node metadata
sdks/java/src/main/java/org/byteveda/taskito/workflows/GateAction.java, sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java, sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java, sdks/java/src/main/java/org/byteveda/taskito/workflows/PlanNode.java, sdks/java/src/main/java/org/byteveda/taskito/workflows/Workflow.java
Defines gate outcome and configuration types, adds gate fields to step and plan node models, and adds the Workflow.gate(...) builder API with the gate task sentinel.
Submit workflow and JNI contracts
crates/taskito-java/src/workflows/mod.rs, sdks/java/src/main/java/org/byteveda/taskito/DefaultTaskito.java, sdks/java/src/main/java/org/byteveda/taskito/spi/QueueBackend.java, sdks/java/src/main/java/org/byteveda/taskito/internal/NativeWorkflows.java, sdks/java/src/main/java/org/byteveda/taskito/internal/JniQueueBackend.java, sdks/java/test-support/src/main/java/org/byteveda/taskito/test/InMemoryQueueBackend.java
Extends workflow submission with parent linkage fields, includes gate metadata in step specs and plan nodes, exposes workflow-name lookup, and adds JNI methods for gate and deferred-node state transitions.
WorkflowTracker promotion and Worker gate control
sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java, sdks/java/src/main/java/org/byteveda/taskito/worker/Worker.java
Adds deferred payload registration, gate parking and timeout resolution, successor promotion, run cleanup, tracker-backed gate approval and rejection, builder wiring, and shutdown cleanup.
Gate workflow integration tests
sdks/java/src/test/java/org/byteveda/taskito/WorkflowGateTest.java
Adds end-to-end coverage for manual approval, manual rejection, timeout auto-approval, timeout auto-rejection, and gate node status polling.
Java 17 build and CI updates
sdks/java/build.gradle.kts, sdks/java/processor/build.gradle.kts, sdks/java/test-support/build.gradle.kts, sdks/java/graalvm-smoke/build.gradle.kts, sdks/java/gradle/wrapper/gradle-wrapper.properties, .github/actions/setup-java/action.yml, .github/workflows/ci-java.yml
Updates build targets, plugin versions, wrapper distribution, action metadata, and CI matrix and task selection to Java 17 and the new JDK coverage set.

Sequence Diagram(s)

sequenceDiagram
  participant DefaultTaskito
  participant JniQueueBackend
  participant NativeWorkflows
  participant WorkflowTracker
  participant RustJNI

  DefaultTaskito->>JniQueueBackend: submitWorkflow(...)
  JniQueueBackend->>NativeWorkflows: submitWorkflow(handle, ..., parentRunId, parentNodeName)
  NativeWorkflows->>RustJNI: Java_org_byteveda_taskito_internal_NativeWorkflows_submitWorkflow
  WorkflowTracker->>JniQueueBackend: resolveWorkflowGate(runId, nodeName, approved, error)
  JniQueueBackend->>NativeWorkflows: resolveWorkflowGate(handle, runId, nodeName, approved, error)
  NativeWorkflows->>RustJNI: Java_org_byteveda_taskito_internal_NativeWorkflows_resolveWorkflowGate
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~100 minutes

Possibly related PRs

  • ByteVeda/taskito#304: Updates the same Java CI setup and setup-java metadata touched here.
  • ByteVeda/taskito#306: Extends the workflow plan and JNI metadata path that this PR further expands for gate and sub-workflow control.
  • ByteVeda/taskito#309: Also changes the Java workflow matrix and related CI runtime configuration.

Poem

🐰 A gate now hops from code to plan,
With timers, choices, and parent span.
Approve or reject, the trails align,
Java 17 gleams in steady shine.
Hops, hops, hooray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: raising the Java baseline to 17 and adding workflow gate support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/java-workflows-gates

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 PMD (7.25.0)
sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java

[ERROR] Cannot load ruleset .coderabbit-pmd-ruleset.xml: Cannot resolve rule/ruleset reference '.coderabbit-pmd-ruleset.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java

[ERROR] Cannot load ruleset .coderabbit-pmd-ruleset.xml: Cannot resolve rule/ruleset reference '.coderabbit-pmd-ruleset.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.

sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java

[ERROR] Cannot load ruleset .coderabbit-pmd-ruleset.xml: Cannot resolve rule/ruleset reference '.coderabbit-pmd-ruleset.xml'. Make sure the resource is a valid file or URL and is on the CLASSPATH. Use --debug (or a fine log level) to see the current classpath.
[WARN] Progressbar rendering conflicts with reporting to STDOUT. No progressbar will be shown. Try running with argument -r to output the report to a file instead.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/taskito-java/src/workflows/mod.rs (1)

571-580: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Preserve the run’s queue default in plan metadata.

getWorkflowPlan still serializes only the per-step queue. Deferred jobs created later by WorkflowTracker cannot recover the queue_default that was used for static jobs at submit time, so deferred successors can be enqueued on the wrong default queue. Persist or expose the effective queue for deferred nodes instead of relying on PlanNode.queueOrDefault().

Based on learnings, getWorkflowPlan may omit the run default queue, which later breaks deferred job creation in WorkflowTracker; explicit .queue(...) is only the current workaround and the long-term fix is native serialization of the run default queue.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/taskito-java/src/workflows/mod.rs` around lines 571 - 580, The
workflow plan serialization currently drops the run-level queue default, so
deferred jobs later built by WorkflowTracker can’t recover the effective queue
and may use the wrong one. Update getWorkflowPlan to persist or expose the
effective queue for deferred nodes, using PlanNode.queueOrDefault() or an
equivalent resolved queue field instead of only serializing the per-step queue.
Make sure the plan metadata includes enough information for WorkflowTracker to
enqueue deferred successors with the same default queue that was active at
submit time.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/taskito-java/src/workflows/mod.rs`:
- Around line 230-232: The workflow reuse path in mod.rs is only checking same
DAG name/version, but `StepMetadata` fields like `condition`, `gate`, and
`sub_workflow` can change execution behavior and must be part of compatibility.
Update the existing-definition lookup in the workflow step handling code to
compare `step_meta` as well, or reject reuse and require a version bump when the
metadata differs. Use the `StepMetadata`/step reuse logic around the
`condition`, `gate`, and `sub_workflow` assignment to locate the compatibility
check and ensure stale metadata cannot be reused.
- Around line 588-610: `workflowNameForRun` currently returns only `def.name`,
which can collide across workflow versions and make deferred payload resolution
pick the wrong workflow. Update
`Java_org_byteveda_taskito_internal_NativeWorkflows_workflowNameForRun` and the
related tracker path to expose a versioned workflow identity, or add a separate
version accessor, and ensure the Java tracker caches deferred payloads using
both workflow name and version. Use the existing `wf.get_workflow_run(...)` and
`get_workflow_definition_by_id(...)` lookup flow to retrieve the version
alongside the name and return/store both fields consistently.
- Around line 1050-1055: The node is still being marked Skipped in the workflow
update flow even when queue.storage.cancel_job fails, which can leave a running
bound job behind. In the workflow handling around wf.get_workflow_node, capture
and propagate the cancel_job result instead of discarding it, or only suppress
explicitly safe cases like already terminal/not found, and only call
wf.update_workflow_node_status to Skipped after cancellation has succeeded.

In `@sdks/java/src/main/java/org/byteveda/taskito/DefaultTaskito.java`:
- Around line 459-460: The workflow definition reuse logic is too permissive:
`DefaultTaskito` only compares DAG topology, so changes to behavior-bearing gate
metadata can be ignored and stale `StepMetadata.gate` may be reused. Update the
definition compatibility check in the native submit path to include step
metadata (especially gate fields encoded via `encodeGate`), or explicitly reject
resubmits under the same version when metadata drifts. Make sure the stored
definition used later by the tracker cannot silently carry over old gate
timeout/action/message settings.

In `@sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java`:
- Around line 30-37: Reject null in the GateConfig.timeout factory methods: both
timeout(Duration, GateAction) and timeout(Duration, GateAction, String) should
validate that the timeout argument is non-null instead of passing it through to
the record constructor, since GateConfig currently treats a null timeout as an
indefinite manual gate. Add an explicit null check or equivalent validation in
these timeout overloads so misconfigured auto-resolution paths fail fast rather
than creating a wait-forever gate.

In `@sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java`:
- Around line 120-136: The public Step.Builder.gate(...) setter is allowing
normal task steps to be marked as gates, but the workflow execution path treats
any step with gate != null as a deferred control node and skips enqueuing its
task payload. Update Step.Builder.build() and related gate validation so gates
are only allowed on Workflow.gate(...) / __gate__ control nodes, or otherwise
change the execution/tracking flow to enqueue the task after approval; use the
Step.Builder.gate(...) and Step.build() symbols to locate the fix.

In `@sdks/java/src/main/java/org/byteveda/taskito/workflows/Workflow.java`:
- Around line 82-90: The gate path in Workflow.gate currently leaves downstream
deferred nodes vulnerable to the getWorkflowPlan queue-default gap, so
WorkflowTracker can recreate them on "default" instead of the intended lane.
Update the gate/deferred-node handling in Workflow.gate and the related workflow
plan generation so the run default queue is propagated for deferred successors,
or enforce/fail fast when a deferred step lacks an explicit .queue(...) and
document that requirement clearly in the gate API behavior.

In `@sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java`:
- Around line 253-268: In WorkflowTracker.resolveGate, only consume the
idempotency entry for gates that are actually parked by checking the node
snapshot state is WAITING_APPROVAL before adding to resolvedGates. Keep the
resolvedGates key until after backend.resolveWorkflowGate(runId, nodeName,
approved, error) succeeds, and if resolution fails, do not leave the gate marked
resolved. Use the existing resolveGate, resolvedGates, gateTimers, and
backend.resolveWorkflowGate symbols to update the flow so early
approveGate/rejectGate calls on PENDING nodes do not promote successors
prematurely.
- Around line 213-225: In WorkflowTracker.promoteOutcome, the promotedNodes
dedupe is applied before the promotion side effects, so if enterGate(...) or
createDeferredJobFor(...) throws the node remains half-promoted and future
retries will be blocked. Update the logic around the GateKey add check to roll
back the dedupe entry when promotion fails, or explicitly mark the node failed
before returning, so subsequent outcome handling can retry or fail cleanly.
Focus on the promoteOutcome flow and the enterGate/createDeferredJobFor paths.

---

Outside diff comments:
In `@crates/taskito-java/src/workflows/mod.rs`:
- Around line 571-580: The workflow plan serialization currently drops the
run-level queue default, so deferred jobs later built by WorkflowTracker can’t
recover the effective queue and may use the wrong one. Update getWorkflowPlan to
persist or expose the effective queue for deferred nodes, using
PlanNode.queueOrDefault() or an equivalent resolved queue field instead of only
serializing the per-step queue. Make sure the plan metadata includes enough
information for WorkflowTracker to enqueue deferred successors with the same
default queue that was active at submit time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f4266d8c-68c9-4cf3-9786-352ac534150e

📥 Commits

Reviewing files that changed from the base of the PR and between 5176752 and 382a54f.

📒 Files selected for processing (19)
  • .github/actions/setup-java/action.yml
  • .github/workflows/ci-java.yml
  • crates/taskito-java/src/workflows/mod.rs
  • sdks/java/build.gradle.kts
  • sdks/java/processor/build.gradle.kts
  • sdks/java/src/main/java/org/byteveda/taskito/DefaultTaskito.java
  • sdks/java/src/main/java/org/byteveda/taskito/internal/JniQueueBackend.java
  • sdks/java/src/main/java/org/byteveda/taskito/internal/NativeWorkflows.java
  • sdks/java/src/main/java/org/byteveda/taskito/spi/QueueBackend.java
  • sdks/java/src/main/java/org/byteveda/taskito/worker/Worker.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/GateAction.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/PlanNode.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/Workflow.java
  • sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java
  • sdks/java/src/test/java/org/byteveda/taskito/WorkflowGateTest.java
  • sdks/java/test-support/build.gradle.kts
  • sdks/java/test-support/src/main/java/org/byteveda/taskito/test/InMemoryQueueBackend.java

Comment thread crates/taskito-java/src/workflows/mod.rs
Comment thread crates/taskito-java/src/workflows/mod.rs
Comment thread crates/taskito-java/src/workflows/mod.rs
Comment thread sdks/java/src/main/java/org/byteveda/taskito/DefaultTaskito.java
Comment thread sdks/java/src/main/java/org/byteveda/taskito/workflows/GateConfig.java Outdated
Comment thread sdks/java/src/main/java/org/byteveda/taskito/workflows/Step.java
Comment thread sdks/java/src/main/java/org/byteveda/taskito/workflows/WorkflowTracker.java Outdated
Gradle 8.12 cannot run on JDK 25; bump wrapper to 9.6.1, spotless 7.2.1, vanniktech 0.37.0. Migrate registering->register and drop the removed SonatypeHost arg for Gradle 9 / plugin compat.
@pratyush618 pratyush618 changed the title feat(java): Java 17 baseline + workflow approval gates feat(java): raise baseline to 17 and add workflow gates Jun 29, 2026
@pratyush618
pratyush618 merged commit 12f8e38 into master Jun 29, 2026
38 checks passed
@pratyush618
pratyush618 deleted the feat/java-workflows-gates branch June 29, 2026 13:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant